package cn.amossun.starter.event.property;

import cn.hutool.core.collection.CollectionUtil;
import lombok.Data;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Data
public final class EventContext {

    private final AtomicInteger counter = new AtomicInteger();

    private static final Map<String, List<ListenerInvokeHandler>> invokeHandlerMap = new HashMap<>();

    private List<EventQueueContext> queueContexts = new ArrayList<>(10);

    private List<EventExchangeContext> exchangeContexts = new ArrayList<>(10);

    private List<EventBindingContext> bindingContexts = new ArrayList<>(10);

    private List<ListenerContext> listenerContexts = new ArrayList<>(10);

    private final Map<String, MessageListenerContainer> listenerContainers =
            new ConcurrentHashMap<String, MessageListenerContainer>();

    public void putListenerContainer(MessageListenerContainer messageListenerContainer){
        this.listenerContainers.put(getEndpointId(), messageListenerContainer);
    }

    public Collection<MessageListenerContainer> getListenerContainers() {
        return Collections.unmodifiableCollection(this.listenerContainers.values());
    }

    private String getEndpointId() {
        return "org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#" + this.counter.getAndIncrement();
    }

    public void addQueue(EventQueueContext eventQueueContext) {
        if(eventQueueContext != null) {
            this.queueContexts.add(eventQueueContext);
        }
    }

    public void addQueues(List<EventQueueContext> eventQueueContexts) {
        if(CollectionUtil.isNotEmpty(eventQueueContexts)) {
            this.queueContexts.addAll(eventQueueContexts);
        }
    }

    public void addExchange(EventExchangeContext exchange) {
        if(exchange != null) {
            this.exchangeContexts.add(exchange);
        }
    }

    public void addExchanges(List<EventExchangeContext> exchanges) {
        if(CollectionUtil.isNotEmpty(exchanges)) {
            this.exchangeContexts.addAll(exchanges);
        }
    }

    public void addBinding(String beanName, String methodName, EventBindingContext binding) {
        if(binding != null) {
            this.bindingContexts.add(binding);
        }
    }

    public void addBindings(String beanName, String methodName, List<EventBindingContext> bindings) {
        if(CollectionUtil.isNotEmpty(bindings)) {
            this.bindingContexts.addAll(bindings);
        }
    }

    public List<ListenerInvokeHandler> getInvokeHandlers(String key) {
        return invokeHandlerMap.get(key);
    }

    public Map<String, List<ListenerInvokeHandler>> getInvokeHandlerMap() {
        return invokeHandlerMap;
    }

}
